package com.cheng.utils;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * 图片处理工具类
 * @author cheng-qiang
 * @date 2022年08月11日16:19
 */
public class ThumbnailsImageUtils {

    private final static Logger logger = LoggerFactory.getLogger(ThumbnailsImageUtils.class);

    /**
     * 将原图根据指定大小生产新图
     *
     * @param sourceFilePath 原始图片路径
     * @param width          指定图片宽度
     * @param height         指定图片高度
     * @param targetFilePath 目标图片路径
     * @return 目标图片路径
     */
    public static String thumb(String sourceFilePath, Integer width, Integer height, String targetFilePath) throws IOException {
        Thumbnails.of(sourceFilePath)
                .forceSize(width, height)
                .toFile(targetFilePath);
        return targetFilePath;
    }


    /**
     * 按照比例进行缩放
     *
     * @param sourceFilePath 原始图片路径
     * @param scale          scale(比例)
     * @param targetFilePath 目标图片路径
     * @return 目标图片路径
     */
    public static String scale(String sourceFilePath, Double scale, String targetFilePath) throws IOException {
        Thumbnails.of(sourceFilePath)
                .scale(scale)
                .toFile(targetFilePath);
        return targetFilePath;
    }


    /**
     * 不按照比例，指定大小进行缩放
     *
     * @param sourceFilePath 原始图片路径
     * @param width          指定图片宽度
     * @param height         指定图片高度
     * @param targetFilePath 目标图片路径
     *                       keepAspectRatio(false) 默认是按照比例缩放的
     * @return 目标图片路径
     */
    public static String size(String sourceFilePath, Integer width, Integer height, float quality, String targetFilePath) throws IOException {
        Thumbnails.of(sourceFilePath)
                .size(width, height)
                .outputQuality(quality)
                .keepAspectRatio(false)
                .toFile(targetFilePath);
        return targetFilePath;
    }


    /**
     * 指定大小和角度旋转
     *
     * @param sourceFilePath 原始图片路径
     * @param width          指定图片宽度
     * @param height         指定图片高度
     * @param rotate         rotate(角度),正数：顺时针 负数：逆时针
     * @param targetFilePath 目标图片路径
     * @return 目标图片路径
     */
    public static String rotate(String sourceFilePath, Integer width, Integer height, Double rotate, String targetFilePath) throws IOException {
        Thumbnails.of(sourceFilePath)
                .size(width, height)
                .rotate(rotate)
                .toFile(targetFilePath);
        return targetFilePath;
    }


    /**
     * 指定角度旋转
     *
     * @param sourceFilePath 原始图片路径
     * @param rotate         rotate(角度),正数：顺时针 负数：逆时针
     * @param targetFilePath 目标图片路径
     * @return 目标图片路径
     */
    public static String rotate(String sourceFilePath, Double rotate, String targetFilePath) throws IOException {
        Thumbnails.of(sourceFilePath)
                .rotate(rotate)
                .toFile(targetFilePath);
        return targetFilePath;
    }


    /**
     * @param sourceFilePath 原始图片路径
     * @param width          指定图片宽度
     * @param height         指定图片高度
     * @param position       水印位置
     * @param waterFile      水印文件
     * @param opacity        水印透明度
     * @param quality        输出文件的质量
     * @param targetFilePath 目标图片路径
     * @return 目标图片路径
     */
    public static String watermark(String sourceFilePath, Integer width, Integer height, Positions position, String waterFile, float opacity, float quality, String targetFilePath) throws IOException {
        Thumbnails.of(sourceFilePath)
                .size(width, height)
                .watermark(position, ImageIO.read(new File(waterFile)), opacity)
                .outputQuality(quality)
                .toFile(targetFilePath);
        return targetFilePath;
    }


    public static BufferedImage watermarkList(BufferedImage buffImg, int length, File[] waterFileArray) throws IOException {
        int x = 0;
        int y = 0;
        if (buffImg == null) {
            // 获取底图
            buffImg = new BufferedImage(1200, 1200, BufferedImage.SCALE_SMOOTH);
        } else {
            x = (length % 30) * 40;
            y = (length / 30) * 40;
        }
        // 创建Graphics2D对象，用在底图对象上绘图
        Graphics2D g2d = buffImg.createGraphics();
        // 将图像填充为白色
        g2d.setColor(Color.WHITE);
        g2d.fillRect(x, y, 1200, 40 * (waterFileArray.length + length));
        for (int i = 0; i < waterFileArray.length; i++) {
            // 获取层图
            BufferedImage waterImg = ImageIO.read(waterFileArray[i]);
            // 获取层图的宽度
            int waterImgWidth = waterImg.getWidth();
            // 获取层图的高度
            int waterImgHeight = waterImg.getHeight();
            // 在图形和图像中实现混合和透明效果
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1));
            // 绘制
            int j = i / 30;
            int index = i - j * 30;
            g2d.drawImage(waterImg, waterImgWidth * index + 1, waterImgHeight * j, waterImgWidth, waterImgHeight, null);

        }

        // 释放图形上下文使用的系统资源
        g2d.dispose();
        return buffImg;
    }

    /**
     * @param sourceFilePath 原始图片路径
     * @param waterFile      水印文件
     * @param targetFilePath 目标图片路径
     *                       透明度默认值0.5f，质量默认0.8f
     * @return 目标图片路径
     */
    public static String watermark(String sourceFilePath, String waterFile, String targetFilePath) throws IOException {
        Image image = ImageIO.read(new File(waterFile));
        Integer width = image.getWidth(null);
        Integer height = image.getHeight(null);
        return watermark(sourceFilePath, width, height,
                Positions.BOTTOM_RIGHT, waterFile, 0.5f, 0.8f, targetFilePath);
    }


    /**
     * 将图片转化为指定大小和格式的图片
     *
     * @param sourceFilePath
     * @param width
     * @param height
     * @param format
     * @param targetFilePath
     * @return
     * @throws IOException
     */
    public static String changeFormat(String sourceFilePath, Integer width, Integer height, String format, String targetFilePath) throws IOException {
        Thumbnails.of(sourceFilePath)
                .size(width, height)
                .outputQuality(0.8f)
                .outputFormat(format)
                .toFile(targetFilePath);
        return targetFilePath;
    }


    /**
     * 根据原大小转化指定格式
     *
     * @param sourceFilePath
     * @param format
     * @param targetFilePath
     * @return
     * @throws IOException
     */
    public static String changeFormat(String sourceFilePath, String format, String targetFilePath) throws IOException {
        Image image = ImageIO.read(new File(sourceFilePath));
        Integer width = image.getWidth(null);
        Integer height = image.getHeight(null);
        Thumbnails.of(sourceFilePath)
                .size(width, height)
                .outputFormat(format)
                .toFile(targetFilePath);
        return targetFilePath;
    }

    /**
     * 输出到输出流
     *
     * @param sourceFilePath
     * @param targetFilePath
     * @return
     * @throws IOException
     */
    public static String toOutputStream(String sourceFilePath, String targetFilePath) throws IOException {
        OutputStream os = new FileOutputStream(targetFilePath);
        Thumbnails.of(sourceFilePath).toOutputStream(os);
        return targetFilePath;
    }


    /**
     * 输出到BufferedImage
     *
     * @param sourceFilePath
     * @param format
     * @param targetFilePath
     * @return
     * @throws IOException
     */
    public static String asBufferedImage(String sourceFilePath, String format, String targetFilePath) throws IOException {
        /**
         * asBufferedImage() 返回BufferedImage
         */
        BufferedImage thumbnail = Thumbnails.of(sourceFilePath).size(1280, 1024).asBufferedImage();
        ImageIO.write(thumbnail, format, new File(targetFilePath));
        return targetFilePath;
    }
}
